package com.ruizhong.centercontroll.task;

import com.ruizhong.centercontroll.entity.CommandTask;
import com.ruizhong.centercontroll.entity.TCommand;
import com.ruizhong.centercontroll.entity.TScheduledTask;
import com.ruizhong.centercontroll.service.TCommandService;
import com.ruizhong.centercontroll.service.TScheduledTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;

@Component
@Slf4j
public class ScheduledTask {

    @Autowired
    private TScheduledTaskService tScheduledTaskService;

    public ScheduledExecutorService scheduler;

    public Map<DayOfWeek, String> dayOfWeekMap;

    @Autowired
    private TCommandService tCommandService;

    /**
     * @param
     * @return
     * @Description: 每次程序启动或者每晚0点执行该方法, 当前当天所有 定时任务，并加载到定时任务线程池中
     * @version v1.0
     * @author fengweijie
     * @date 2024/12/6 15:37
     */
    @PostConstruct
    public void init() {
        scheduler = Executors.newScheduledThreadPool(5);
        // 获取今天的日期
        LocalDate today = LocalDate.now();
// 创建一个DateTimeFormatter实例，指定格式为yyyy-MM-dd
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 将今天的日期格式化为字符串
        String formattedDate = today.format(formatter);
        // 获取今天是周几
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        // 创建一个映射，将DayOfWeek映射到中文表示
        if (CollectionUtils.isEmpty(dayOfWeekMap)) {
            dayOfWeekMap = new HashMap<>();
            dayOfWeekMap.put(DayOfWeek.MONDAY, "周一");
            dayOfWeekMap.put(DayOfWeek.TUESDAY, "周二");
            dayOfWeekMap.put(DayOfWeek.WEDNESDAY, "周三");
            dayOfWeekMap.put(DayOfWeek.THURSDAY, "周四");
            dayOfWeekMap.put(DayOfWeek.FRIDAY, "周五");
            dayOfWeekMap.put(DayOfWeek.SATURDAY, "周六");
            dayOfWeekMap.put(DayOfWeek.SUNDAY, "周日");
        }
        // 获取中文表示并打印结果
        String chineseDayOfWeek = dayOfWeekMap.get(dayOfWeek);
        List<TScheduledTask> scheduledTasks = tScheduledTaskService.lambdaQuery()
                .eq(TScheduledTask::getExecuteDate, formattedDate)
                .or()
                .like(TScheduledTask::getRepeatGroupData, chineseDayOfWeek)
                .list();
        HashMap<String, TScheduledTask> timeMapScheduledTasks = new HashMap<>();
        for (TScheduledTask scheduledTask : scheduledTasks) {
            String executeTime = scheduledTask.getExecuteTime();
            TScheduledTask tScheduledTask = timeMapScheduledTasks.get(executeTime);
            if (tScheduledTask != null && scheduledTask.getPriority() > tScheduledTask.getPriority()) {
                timeMapScheduledTasks.put(executeTime, scheduledTask);
            }
        }
        timeMapScheduledTasks.forEach(new BiConsumer<String, TScheduledTask>() {
            @Override
            public void accept(String timeString, TScheduledTask tScheduledTask) {
                // 定义时间字符串的格式
                DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH-mm-ss");
                // 解析给定的时间字符串为 LocalTime
                LocalTime time = LocalTime.parse(timeString, timeFormatter);
                // 使用当前的日期和解析的时间创建 LocalDateTime 对象
                LocalDateTime dateTime = LocalDateTime.of(today, time);
                long delay = ChronoUnit.MILLIS.between(LocalDateTime.now(), dateTime);
                Integer smallDelay = 0;
                if (delay >= 0) {
                    List<TCommand> commandListByMain = tCommandService.getCommandListByMain(tScheduledTask.getId(), "SCHEDULE", "schedule");
                    for (TCommand tCommand : commandListByMain) {
                        Integer eachDelay = tCommand.getDelay();
                        smallDelay += (eachDelay == null ? 0 : eachDelay);
                        tCommand.setDelay(smallDelay);
                        CommandTask commandTask = new CommandTask(tCommand, tCommandService);
                        scheduler.schedule(commandTask, delay, TimeUnit.MILLISECONDS);
                    }
                }
            }
        });
    }

    @PreDestroy
    public void preDestroy() {
        cleanScheduler();
    }

    public void reInit() {
        cleanScheduler();
        init();
    }

    private void cleanScheduler() {
        scheduler.shutdownNow();
        scheduler = null;
    }

    @Scheduled(cron = "0 0 0 * * ?")
    public void initTaskArr() {
        log.info("触发任务重加载");
        reInit();
    }

}
